unit SrtTimeLocateExecuter;

interface
uses SrtActionExecuter,SrtSubTitleDataTable,SrtTimeManager;

type TSrtTimeLocateExecuter=class(TSrtActionExecuter)
  private
    refTimeMan:TSrtTimeManager;

    //procedure LocateTimeSequentialSearch(refSeconds:Double);
    procedure LocateTimeBinarySearch(refSeconds:Double);
  public
    procedure LocateTime(refSeconds:Double);
    function GetDisplayingSubtitle(refSeconds:Double):string;

    constructor Create(initSubTitle:TSrtSubTitleDataTable);override;
    destructor Destroy;override;
end;

implementation
{ TTimeLocateExecuter }


constructor TSrtTimeLocateExecuter.Create(initSubTitle: TSrtSubTitleDataTable);
begin
    inherited;
    refTimeMan:=TSrtTimeManager.Create;
end;

destructor TSrtTimeLocateExecuter.Destroy;
begin
    refTimeMan.Free;
    inherited;
end;

procedure TSrtTimeLocateExecuter.LocateTime(refSeconds: Double);
begin
    LocateTimeBinarySearch(refSeconds);
    //LocateTimeSequentialSearch(refSeconds);
end;

procedure TSrtTimeLocateExecuter.LocateTimeBinarySearch(refSeconds: Double);
var
    refTime:string;
    copySubTitle:TSrtSubTitleDataTable;
    minRecNo,maxRecNo:integer;
begin
    refTimeMan.TotalMilliSeconds:=Trunc(refSeconds*1000);
    refTime:=refTimeMan.ToString;

    copySubTitle:=TSrtSubTitleDataTable.Create(nil);
    copySubTitle.CopyFrom(SrtSubTitle);
    //copySubTitle.Data:=SrtSubTitle.Data;

    with copySubTitle do begin
        DisableControls;
        FieldDefs.Delete(ContentFieldIndex);

        First;
        if Eof=false then begin
            minRecNo:=1;
            maxRecNo:=RecordCount;

            repeat
                RecNo:=(minRecNo+maxRecNo) div 2;

                if refTime>=CurrentTimeFrom then begin
                    Next;
                    if refTime<CurrentTimeFrom then begin
                        Prior;
                        if refTime>CurrentTimeTo then next;
                        break;
                    end else begin
                        minRecNo:=RecNo;
                    end;
                end else begin
                    maxRecNo:=RecNo;
                end;
            until (maxRecNo-minRecNo<=0);

            if SrtSubTitle.RecNo<>copySubTitle.RecNo then SrtSubTitle.RecNo:=copySubTitle.RecNo;
        end;
    end;

    copySubTitle.Free;
end;

{procedure TSrtTimeLocateExecuter.LocateTimeSequentialSearch(refSeconds: Double);
var
    refTime:string;
    copySubTitle:TSrtSubTitleDataTable;
begin
    refTimeMan.TotalMilliSeconds:=Trunc(refSeconds*1000);
    refTime:=refTimeMan.ToString;

    copySubTitle:=TSrtSubTitleDataTable.Create(nil);
    copySubTitle.Data:=SrtSubTitle.Data;

    with copySubTitle do begin
        DisableControls;
        FieldDefs.Delete(ContentFieldIndex);

        First;
        if EOF=false then begin
            while refTime >= CurrentTimeFrom do begin
                Next;
                if EOF then break;
            end;

            //if not EOF then Prior;
            if SrtSubTitle.RecNo<>copySubTitle.RecNo then SrtSubTitle.RecNo:=copySubTitle.RecNo;
        end;

    end;

    copySubTitle.Free;
end;}

function TSrtTimeLocateExecuter.GetDisplayingSubtitle(refSeconds: Double):string;
const
    separator:string=#13#10;
var
    refTime:string;
    copySubTitle:TSrtSubTitleDataTable;
    displayingSubtitle:string;
begin
    refTimeMan.TotalMilliSeconds:=Trunc(refSeconds*1000);
    refTime:=refTimeMan.ToString;

    //copySubTitle:=TSrtSubTitleDataTable.Create(nil);
    copySubTitle:=SrtSubTitle;
    with copySubTitle do begin
        //CopyFrom(SrtSubTitle);
        //Data:=SrtSubTitle.Data;
        DisableControls;

        Filter:=TimeFromField +' <= ''' + refTime + ''' AND ' + TimeToField + ' >= ''' + refTime + '''';
        Filtered:=true;

        displayingSubtitle:='';
        First;
        while not Eof do begin
            if displayingSubtitle<>'' then displayingSubtitle:=displayingSubtitle+separator;
            displayingSubtitle:=displayingSubtitle+CurrentContent;
            next;
        end;

        ClearFilter;
        EnableControls;
        //Free;
    end;

    exit(displayingSubtitle);
end;

end.
